mod base64;
mod csv;
mod genpass;
mod http;
mod jsonwt;
mod text;
use std::path::Path;
use std::path::PathBuf;

pub use self::base64::Base64DecodeOpts;
pub use self::base64::Base64EncodeOpts;
pub use self::base64::Base64Format;
pub use self::base64::Base64SubCommand;
pub use self::csv::OutputFormat;
pub use self::http::HttpSubCommand;
pub use self::jsonwt::JwtSignOpts;
pub use self::jsonwt::JwtSubCommand;
pub use self::jsonwt::JwtVerifyOpts;
use clap::Parser;
pub use csv::CsvOpts;
use enum_dispatch::enum_dispatch;
pub use genpass::GenPassOpts;
pub use http::ServeOpts;
pub use text::TextSignFormat;
pub use text::TextSubCommand;
pub use text::{TextGenerateOpts, TextSignOpts, TextVerifyOpts};
#[derive(Debug, Parser)]
#[command(name="",version,author,about,long_about=None)]
pub struct Opts {
    #[command(subcommand)]
    pub cmd: SubCommand,
}

#[derive(Debug, Parser)]
#[enum_dispatch(CmdExecutor)]
pub enum SubCommand {
    #[command(name = "csv", about = "Show CSV Convert CSV to other formats")]
    Csv(CsvOpts),
    #[command(name = "genpass", about = "generate a passwordss")]
    GenPass(GenPassOpts),

    #[command(subcommand, about = "base64 encoding/decoding")]
    Base64(Base64SubCommand),

    #[command(subcommand, about = " sign/verify text")]
    Text(TextSubCommand),

    #[command(subcommand, about = " http  rpc")]
    Http(HttpSubCommand),

    #[command(subcommand, about = " json web token")]
    Jwt(JwtSubCommand),
}

fn verify_file(filename: &str) -> Result<String, &'static str> {
    if filename == "-" || Path::new(filename).exists() {
        Ok(filename.into())
    } else {
        Err("File does not exist")
    }
}

fn verify_path(s: &str) -> Result<PathBuf, &'static str> {
    let path = Path::new(s);
    if path.exists() && path.is_dir() {
        Ok(path.into())
    } else {
        Err(" path does not exist or is not a directory˝")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_verify_input_file() {
        let ret: String = "Cargo.toml".into();
        let filename = verify_file("Cargo.toml");
        let ddd: Result<String, &str> = Ok(ret);
        assert_eq!(filename, ddd);
    }
}
